package com.infraware.supermanbooks;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import nl.siegmann.epublib.browsersupport.Navigator;
import nl.siegmann.epublib.domain.Book;
import nl.siegmann.epublib.domain.MediaType;
import nl.siegmann.epublib.domain.Metadata;
import nl.siegmann.epublib.domain.Resource;
import nl.siegmann.epublib.domain.Resources;
import nl.siegmann.epublib.domain.Spine;
import nl.siegmann.epublib.domain.TOCReference;
import nl.siegmann.epublib.domain.TableOfContents;
import nl.siegmann.epublib.epub.EpubReader;
import nl.siegmann.epublib.service.MediatypeService;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebViewFragment;
import android.widget.TextView;
import android.widget.Toast;

import com.infraware.supermanbooks.book.BookContent;
import com.infraware.supermanbooks.book.BookContent.BookItem;

/**
 * A fragment representing a single Book detail screen.
 * This fragment is either contained in a {@link BookListActivity} in two-pane mode (on tablets) or
 * a {@link BookDetailActivity} on handsets.
 */
public class BookDetailFragment extends Fragment {
    private final String TAG = "BookDetailFragment";
    /**
     * The fragment argument representing the item ID that this fragment
     * represents.
     */
    public static final String ARG_ITEM_ID = "item_id";

    /**
     * The dummy content this fragment is presenting.
     */
    private BookContent.BookItem mItem;

    private WebView webview;

    public static Book book;

    private StringBuilder tableOfContents;

    private int currentSpineIndex;

    private boolean[] pageLoaded;

    private Toast toast;

    /**
     * Mandatory empty constructor for the fragment manager to instantiate the
     * fragment (e.g. upon screen orientation changes).
     */
    public BookDetailFragment() {
        tableOfContents = new StringBuilder();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getArguments().containsKey(ARG_ITEM_ID)) {
            // Load the dummy content specified by the fragment
            // arguments. In a real-world scenario, use a Loader
            // to load content from a content provider.
            mItem = BookContent.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID));
            toast = Toast.makeText(getActivity(), "", Toast.LENGTH_SHORT);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_book_detail, container, false);
        webview = (WebView)rootView.findViewById(R.id.book_detail);

        webview.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                return false;
            }

            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
                Uri uri = Uri.parse(url);
                String path = uri.getPath();
                Log.d(TAG, "[shouldInterceptRequest] url => " + uri);

                if (path.startsWith("/")) {
                    path = path.substring(1);
                }

                Log.d(TAG, "[shouldInterceptRequest] path => " + path);
                if (book != null) {
                    Resources resources = book.getResources();
                    Resource resource = resources.getByHref(path);
                    Log.d(TAG, "[shouldInterceptRequest] resource => " + resource);
                    if (resource != null) {
                        try {
                            Log.d(TAG, "[shouldInterceptRequest] path => " + path);
                            WebResourceResponse response = new WebResourceResponse(resource.getMediaType().getName(),
                                        resource.getInputEncoding(),
                                        resource.getInputStream());
                            return response;
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
                return super.shouldInterceptRequest(view, url);
            }
        });

        //        webview.loadData("Loading...", "text/plain", null);
        if (mItem != null) {
            new LoadAsyncTask().execute(mItem.path);
        }
        return rootView;
    }

    public void gotoPrevious() {
        Spine spine = book.getSpine();
        if (currentSpineIndex - 1 < spine.size()) {
            if (currentSpineIndex > 0) {
                currentSpineIndex--;
                if (pageLoaded[currentSpineIndex]) {
                    webview.goBack();
                } else {
                    new LoadAsyncTask().execute("");
                }
                return;
            }
        }
        toast.setText("First Page");
        toast.show();
    }

    public void gotoNext() {
        Spine spine = book.getSpine();
        if (currentSpineIndex + 1 < spine.size()) {
            currentSpineIndex++;
            if (pageLoaded[currentSpineIndex]) {
                webview.goForward();
            } else {
                new LoadAsyncTask().execute("");
            }
            return;
        }
        toast.setText("Last Page");
        toast.show();
    }

    private void loadTableOfContents(List<TOCReference> tocReferences, int depth) {
        if (tocReferences == null) {
            return;
        }

        try {
            for (TOCReference tocReference : tocReferences) {
                tableOfContents.append("<div>");
                for (int i = 0; i < depth; i++) {
                    tableOfContents.append("&nbsp;&nbsp;&nbsp;&nbsp;");
                }
                tableOfContents.append(tocReference.getTitle());
                tableOfContents.append("</div>");
                loadTableOfContents(tocReference.getChildren(), depth);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private String loadContents(int index) {
        Spine spine = book.getSpine();
        int size = spine.size();
        if (index < size) {
            try {

                Resource resource = spine.getResource(index);
                if (resource.getMediaType() == MediatypeService.XHTML) {
                    String html = new String(resource.getData());
                    return html;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            new Throwable("index is out of bounds.");
        }
        return "";
    }

    private class LoadAsyncTask extends AsyncTask<String, Integer, String> {

        @Override
        protected String doInBackground(String... params) {
            tableOfContents = new StringBuilder();

            if (params.length == 0) {
                return "";
            }

            String path = params[0];
            try {
                if (path != null && path.length() != 0) {
                    File file = new File(path);
                    FileInputStream in = new FileInputStream(file);
                    EpubReader reader = new EpubReader();
                    book = reader.readEpub(in);
                    pageLoaded = new boolean[book.getSpine().size()];
                    in.close();
                }
                String html = loadContents(currentSpineIndex);
                return html;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }

        @Override
        protected void onPostExecute(String html) {
            Log.d(TAG, "[onPostExecute] tableOfContents(" + html.length() + ")\n" + html);
            if (html.length() == 0) {
                html = "<div>Title : " + mItem.title
                       + "</div><div>Author : "
                       + mItem.author
                       + "</div><div>id : "
                       + mItem.id
                       + "</div><div>path : "
                       + mItem.path
                       + "</div>";
            } else {
                pageLoaded[currentSpineIndex] = true;
            }
            //            webview.loadData(html, "text/html", null);

            String baseUrl = "content://" + getActivity().getPackageName();// + mItem.path.replace(".epub", "/");
            //            String baseUrl = mItem.path.replace(".epub", "/");
            webview.loadDataWithBaseURL(baseUrl, html, "text/html", null, null);
            Log.d(TAG, "[onPostExecute] baseUrl => " + baseUrl);
        }
    }
}
